package com.baima46.core;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelFileUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baima46.model.ExcelInfo;
import com.baima46.model.HeaderCell;
import com.baima46.model.SheetInfo;
import com.baima46.utils.HttpUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.streaming.SXSSFSheet;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

/**
 * @Description 导出处理类
 * @Author yuan cong
 * @Date 2020/12/7 0007
 */
public class ExportHandle {
    /**
     * 导出excel到内存
     * @param excelInfo 导出信息
     */
    private static ExcelWriter exportExcel(ExcelInfo excelInfo){
        // 通过工具类创建writer,true表示生成xlsx格式的excel
        ExcelWriter writer = ExcelUtil.getBigWriter();
        // 重命名第一个Sheet的名称，不然会默认多出一个Sheet1的页
        writer.renameSheet(0, excelInfo.getSheetList().get(0).getSheetName());

        for (SheetInfo sheet : excelInfo.getSheetList()) {
            // 指定要写出的 Sheet 页
            writer.setSheet(sheet.getSheetName());

            int maxRow = 0;

            // 合并单元格后的标题行，使用默认标题样式
            for (HeaderCell headerCell : sheet.getHeaderCellList()) {
                //如果是单个单元格，则写入
                if (headerCell.getFirstRow() == headerCell.getLastRow() && headerCell.getFirstColumn() == headerCell.getLastColumn()){
                    writer.writeCellValue(headerCell.getFirstColumn(),headerCell.getFirstRow(),headerCell.getName());
                    writer.setStyle(writer.getHeadCellStyle(),headerCell.getFirstColumn(),headerCell.getFirstRow());
                }else {
                    writer.merge(headerCell.getFirstRow(),headerCell.getLastRow(),headerCell.getFirstColumn(),headerCell.getLastColumn(), headerCell.getName(),true);
                }

                if(headerCell.getLastRow() > maxRow){
                    maxRow = headerCell.getLastRow();
                }
            }

            //设置表头自动换行
            CellStyle headCellStyle = writer.getHeadCellStyle();
            headCellStyle.setWrapText(true);

            writer.passRows(maxRow+1);
            // 一次性写出内容，使用默认样式，强制输出标题
            writer.write(sheet.getRowList(), true);

            SXSSFSheet sxssfSheet = (SXSSFSheet)writer.getSheet();
            //上面需要强转SXSSFSheet  不然没有trackAllColumnsForAutoSizing方法
            sxssfSheet.trackAllColumnsForAutoSizing();
            //设置列宽自适应
            writer.autoSizeColumnAll();
            sxssfSheet.untrackAllColumnsForAutoSizing();
        }

        return writer;
    }


    /**
     * 通过http response 导出，文件下载
     * @param excelInfo 导出信息
     */
    public static void exportResponse(ExcelInfo excelInfo) {
        try {
            HttpServletResponse response = HttpUtil.getHttpServletResponse();
            //设置返回的contentType
            HttpUtil.downloadInit(HttpUtil.getHttpServletRequest(), response,excelInfo.getFileName() + excelInfo.getSuffix());
            //out为OutputStream，需要写出到的目标流
            ServletOutputStream out = response.getOutputStream();

            //导出
            exportOut(excelInfo, out);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("HttpServletResponse导出异常！");
        }
    }

    /**
     * 通过 输出流 导出，文件下载
     * @param excelInfo 导出信息
     * @param out 输出流
     */
    public static void exportOut(ExcelInfo excelInfo, OutputStream out) {
        ExcelWriter excelWriter = exportExcel(excelInfo);

        excelWriter.flush(out, true);
        // 关闭writer，释放内存
        excelWriter.close();
        //此处记得关闭输出流
        IoUtil.close(out);
    }

    /**
     * 通过 文件 导出，文件下载
     * @param excelInfo 导出信息
     * @param file 文件
     */
    public static void exportFile(ExcelInfo excelInfo, File file) {
        ExcelWriter excelWriter = exportExcel(excelInfo);

        excelWriter.flush(file);
        // 关闭writer，释放内存
        excelWriter.close();
    }

}
